package com.af.security.auth.login.lock;

import com.af.security.auth.user.detail.AfUserDetails;
import com.af.security.mgt.user.User;
import com.af.security.mgt.user.UserService;
import com.af.security.property.SecurityProperties;
import com.af.task.AfTask;
import com.af.task.AfTaskBaseService;
import com.github.benmanes.caffeine.cache.Cache;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author : zhenyun.su
 * @comment : 用户被锁定，在第一时间内自动解锁
 * @since : 2020-9-3
 */

@Service
public class LockedUserHandler extends AfTaskBaseService<User> {
    public static final Logger logger = LoggerFactory.getLogger(LockedUserHandler.class);

    private UserService userService;
    private SecurityProperties securityProperties;
    private Cache<String, AfUserDetails> securityCache;

    public LockedUserHandler(Cache<String, AfUserDetails> securityCache, UserService userService, SecurityProperties securityProperties) {
        this.securityCache = securityCache;
        this.userService = userService;
        this.securityProperties = securityProperties;
    }

    @Transactional(rollbackFor = Exception.class)
    public void userLocked(String username, Boolean notLocked) {
        User user = userService.userLocked(username, notLocked);
        // 清空缓存，以重新加载
        securityCache.invalidate(username);
        if (user != null){
            addTask(user.getUsername(), user);
        }
    }

    
    /**
     * @comment : 解锁用户， 超过szy.security.loginFailure.unLockUserExpired 分钟
     */
    @Override
    public void handleTaskList() {
        logger.debug("handleTaskList, start");
        Long expired = securityProperties.getLoginFailureUnlockUserExpired();
        LocalDateTime now = LocalDateTime.now();
        List<AfTask<User>> taskList = findAll().subList(0, findAll().size());
        for (AfTask<User> task : taskList) {
            try {
                User user = task.getValue();
                if (now.isAfter(task.getCreatedTime().plusMinutes(expired))) {
                    logger.debug("handleTaskList, User unlocked: {}", user);
                    userService.userLocked(user.getUsername(), true);
                    this.removeTask(task);
                } else {
                    logger.debug("handleTaskList, Unlock time has not come: {}", user);
                }
            } catch (Exception e) {
                logger.error("handleTaskList failed, {}", e);
            }
        }
    }

}

